<?php
/**
 * Created by PhpStorm.
 * User: lee
 * Date: 2018/1/9
 * Time: 下午3:39
 */

namespace Biz\model;

use Biz\module\Classes\GoodsStatus as clsGoodsStatus;
use Biz\validate\GoodsBasicInfo as vGoodsBasicInfo;
use Doraemon\tools\ImgUrl as toolImgUrl;
use Medoo\Medoo;

class GoodsBasicInfo extends \Doraemon\pockets\datebase\BaseDbModel
{

    const _CONFIG_FILE_ = 'db_shop';

    const _CONFIG_SELECT_ = 'db_shop';

    const _DATABASE_ = 'shop';

    const _TABLE_NAME = 'goods_basic_info(gbi)';

    const HAD_ONLINE_NO = 0;//未上过线
    const HAD_ONLINE_YES = 1;//曾经上过线

    const STATUS_PASSED = 1;//已审核 审核通过
    const STATUS_ONLINE = 2;//商品上架
    const STATUS_REJECT = 3;//商品被拒绝 审核不通过
    const STATUS_OFFLINE = 4;//商家下架
    const STATUS_ADM_OFFLINE = 5;//管理员下架
    const STATUS_DELETE = 9;//商品删除
    const STATUS_WAIT_AUDIT = 10;//送审的商品，指的是运营下架的商品被重新编辑


    const STATUS_DESC = [
        self::STATUS_PASSED => '已审核',
        self::STATUS_ONLINE => '已上架',
        self::STATUS_REJECT => '已拒绝',
        self::STATUS_OFFLINE => '已下架',
        self::STATUS_ADM_OFFLINE => '运营下架',
        self::STATUS_DELETE => '已删除',
        self::STATUS_WAIT_AUDIT => '送审中'
    ];
    public static $statusDesc = [
        self::STATUS_PASSED => '已审核',
        self::STATUS_ONLINE => '已上架',
        self::STATUS_REJECT => '已拒绝',
        self::STATUS_OFFLINE => '已下架',
        self::STATUS_ADM_OFFLINE => '运营下架',
        self::STATUS_DELETE => '已删除',
        self::STATUS_WAIT_AUDIT => '送审中'
    ];


    const STATUS_APP_NOMAL = 1; //正常
    const STATUS_APP_DEL = 9; //删除
    const STATUS_APP_OFFLINE = 10; //下架

    const STATUS_APP_MAP = [
        self::STATUS_PASSED => self::STATUS_APP_NOMAL,
        self::STATUS_ONLINE => self::STATUS_APP_NOMAL,
        self::STATUS_REJECT => self::STATUS_APP_DEL,
        self::STATUS_OFFLINE => self::STATUS_APP_OFFLINE,
        self::STATUS_ADM_OFFLINE => self::STATUS_APP_OFFLINE,
        self::STATUS_DELETE => self::STATUS_APP_DEL,
        self::STATUS_WAIT_AUDIT => self::STATUS_APP_OFFLINE
    ];

    const STATUS_APP_CAN_SEE_MAP = [
        self::STATUS_PASSED,
        self::STATUS_ONLINE,
        self::STATUS_ADM_OFFLINE,
        self::STATUS_OFFLINE,
        self::STATUS_WAIT_AUDIT,
    ];
    const STATUS_APP_NORMAL_MAP = [
        self::STATUS_PASSED,
        self::STATUS_ONLINE,
    ];
    const STATUS_APP_OFFLINE_MAP = [
        self::STATUS_ADM_OFFLINE,
        self::STATUS_OFFLINE,
        self::STATUS_WAIT_AUDIT,
    ];

    public static $statusAppMap = [
        self::STATUS_PASSED => self::STATUS_APP_NOMAL,
        self::STATUS_ONLINE => self::STATUS_APP_NOMAL,
        self::STATUS_REJECT => self::STATUS_APP_DEL,
        self::STATUS_OFFLINE => self::STATUS_APP_OFFLINE,
        self::STATUS_ADM_OFFLINE => self::STATUS_APP_OFFLINE,
        self::STATUS_DELETE => self::STATUS_APP_DEL,
        self::STATUS_WAIT_AUDIT => self::STATUS_APP_OFFLINE
    ];

    public static $statusAppCanSeeMap = [
        self::STATUS_PASSED,
        self::STATUS_ONLINE,
        self::STATUS_ADM_OFFLINE,
        self::STATUS_OFFLINE,
        self::STATUS_WAIT_AUDIT,
    ];
    public static $statusAppNormalMap = [
        self::STATUS_PASSED,
        self::STATUS_ONLINE,
    ];
    public static $statusAppOffLineMap = [
        self::STATUS_ADM_OFFLINE,
        self::STATUS_OFFLINE,
        self::STATUS_WAIT_AUDIT,
    ];

    //允许通过createOrEdit操作的字段列表，进行输入转换
    protected static $fields = [
        'goods_id',
        'uid',
        'title' => ['trim', 'strip_tags', 'addslashes'],
        'shop_id',
        'brand_id' => ['intval'],
        'category_id' => ['intval'],
        'second_category_id' => ['intval'],
        'third_category_id' => ['intval'],
        'four_category_id' => ['intval'],
        'last_category_id' => ['intval'],
        'shipping_templ_id' => ['intval'],
        'wiki_id' => ['intval'],
        'status',
        'spec_img',
        'min_price',
        'max_price',
        'stock',
        'sell_total',
    ];

    public static $testShopIds = [
        3192940,
        3657469,
    ];

    //保存商品信息
    public static function createOrEdit($uid, $goodsId, $data, $scenes = null, $method = null)
    {
        try {

            if (is_null($method)) {

                $has = self::has_master(Medoo::raw(' where goods_id=:goodsId for update', [':goodsId' => $goodsId]));

                $method = $has ? 'update' : 'insert';
            }

            if (!is_null($scenes)) {

                if ($method == 'update') {
                    $data['goods_id'] = $goodsId;
                }

                //提交字段进行校验
                if (!vGoodsBasicInfo::validate($data, $scenes)) {

                    $msg = vGoodsBasicInfo::firstError();

                    throw new \Exception($msg);
                }

            }

            $data = self::buidData($data);

            switch ($method) {
                case 'insert':
                    $data['shop_id'] = $uid;
                    $data['uid'] = $uid;
                    $data['brand_id'] = !is_null($data['brand_id']) ? $data['brand_id'] : '';
                    $data['addtime'] = date('Y-m-d H:i:s');
                    $data['wiki_id'] = !empty($data['wiki_id']) ? $data['wiki_id'] : 0;

                    $data['status'] = (isset($data['status']) && !empty($data['status'])) ? $data['status'] : self::STATUS_OFFLINE;
                    if ($data['status'] && $data['status'] == self::STATUS_ONLINE) {
                        $data['had_online'] = self::HAD_ONLINE_YES;
                        $data['first_online_time'] = date('Y-m-d H:i:s');
                    }


                    $ret = self::insert($data);

                    $goodsId = self::id();

                    break;
                case 'update':
                    $ret = self::update($data, ['goods_id' => $goodsId]);

                    break;
            }

            if ($ret->errorCode() !== '00000') {
                throw new \Exception('操作失败,请重试');
            }

            return $goodsId;

        } catch (\Exception $e) {


            throw $e;
        }
    }

    public static function getGoodsInfoByGoodIds($goodsIds, $status = self::STATUS_APP_CAN_SEE_MAP)
    {
        $goods = self::select("*", [
            'goods_id' => $goodsIds,
            'status' => $status
        ]);
        $formatData = [];
        if ($goods) {
            foreach ($goods as $temp) {
                $formatData[$temp['goods_id']] = $temp;
            }
        }
        return $formatData;
    }

    public static function getSameGoodsIdsByWikiIds($wikiIds)
    {
        $goodsInfos = self::select(['goods_id', 'wiki_id'], [
            'wiki_id' => $wikiIds,
            'status' => self::STATUS_APP_NORMAL_MAP
        ]);
        $wikiGoodsIds = [];
        foreach ($goodsInfos as $goodsInfo) {
            $wikiGoodsIds[$goodsInfo['wiki_id']][] = $goodsInfo['goods_id'];
        }
        return $wikiGoodsIds;
    }


    //查询基本信息
    public static function getInfo($goodsId, $column = "*", $fromMater = false)
    {
        if ($fromMater) {
            $info = self::get_master($column, ['goods_id' => $goodsId]);
        } else {
            $info = self::get($column, ['goods_id' => $goodsId]);
        }

        self::formatInfo($info);

        return $info;
    }

    //查询基本信息
    public static function getInfoFromMaster($goodsId, $column = "*")
    {
        $info = self::get_master($column, ['goods_id' => $goodsId]);

        self::formatInfo($info);

        return $info;
    }

    public static function getInfoList($goodsIds, $column = '*')
    {
        $infoList = self::select($column, ['goods_id' => $goodsIds]);

        $infoList = array_column($infoList, null, 'goods_id');

        $infoList = array_map(function ($v) {
            self::formatInfo($v);

            return $v;
        }, $infoList);


        return $infoList;
    }

    public static function formatInfo(&$info, $from = '')
    {
        if (empty($info)) {
            return;
        }
        foreach ($info as $key => &$value) {
            switch ($key) {
                case 'spec_img':
                    $info['spec_img_thumb_url'] = toolImgUrl::getUrl(toolImgUrl::APPTYPE_BIZ, $info['spec_img'], toolImgUrl::IMAGE_SIZE_SQ_THUMB);
                    $info['spec_img_url'] = toolImgUrl::getUrl(toolImgUrl::APPTYPE_BIZ, $info['spec_img'], toolImgUrl::IMAGE_SIZE_ORI_NPHONE);
                    break;
                case 'status':
                    $info['status_desc'] = isset(self::$statusDesc[$value]) ? self::$statusDesc[$value] : "";
                    $info['app_status'] = self::$statusAppMap[$info['status']];
                    break;
                case 'operate_time':
                    $info['operate_time_desc'] = $info['operate_time'] == '0000-00-00 00:00:00' ? '新增下架' : $info['operate_time'];
                    break;
            }
        }

        if ($from == 'adm') {
            $info['actions'] = clsGoodsStatus::getAdminActionList($info['status']);
        }


    }

    public static function getAllGoods($where, $limit, $sort)
    {
        $params['AND'] = $where;
        $params['LIMIT'] = $limit;
        if ($sort) {
            $params['ORDER'] = $sort;
        }
        $result = self::select('*', $params);
        self::formatList($result);
        return $result;
    }

    public static function getGoods($where, $limit, $sort)
    {
        isset($where['status']) ? null : $where['status'] = [
            self::STATUS_PASSED,
            self::STATUS_ONLINE
        ];
        $params['AND'] = $where;
        $params['LIMIT'] = $limit;
        if ($sort) {
            $params['ORDER'] = $sort;
        }
        $result = self::select('*', $params);
        self::formatList($result);
        return $result;
    }

    public static function getGoodsCount($where)
    {
        $count = self::count('*', ['AND' => $where]);
        return $count;
    }

    public static function formatList(&$goodsList)
    {
        foreach ($goodsList as &$row) {
            self::formatInfo($row);
        }
    }

    public static function updateData($data, $where)
    {
        $ret = self::update($data, $where);

        if ($ret) {
            return $ret->rowCount();
        }
    }

    public static function hasShippingTemplGoodsIds($goodsIds)
    {
        return self::has(['goods_id' => $goodsIds, 'status[!]' => [self::STATUS_DELETE]]);
    }

    public static function checkIsAdminOffline($uid, $goodsId)
    {
        $info = self::getInfo($goodsId, ["status"]);
        if ($info['status'] == self::STATUS_ADM_OFFLINE) {
            return true;
        }
        return false;
    }


    public static function checkCanBuy($status)
    {
        if (in_array($status, [self::STATUS_APP_NOMAL])) {
            return true;
        }

        return false;
    }

    public static function getInfos($where = [])
    {
        if ($where) {
            return self::select("*", $where);
        } else {
            return [];
        }
    }

    /*
     *  商品列表
     * **/
    public static function getGoodsList($shopIds, $categoryIds)
    {

        $categoryIds = implode(',', $categoryIds);
        $shopIds = implode(',', $shopIds);

        $sql = "SELECT goods_id FROM (
                  SELECT * FROM goods_basic_info WHERE  `last_category_id` IN ({$categoryIds}) AND `shop_id` IN ({$shopIds}) ORDER  BY `addtime` DESC
               ) AS goods GROUP BY `shop_id`,`last_category_id` ORDER BY `addtime` DESC";

        $goodsIds = self::query($sql)->fetchAll();

        return array_map(function ($v) {
            return $v['goods_id'];
        }, $goodsIds);
    }

    public static function getShopIdsBycategoryIds($categoryIds)
    {

        $shopIds = self::select('shop_id', [
            'AND' => [
                'stock[>]' => 0,
                'status' => self::STATUS_ONLINE,
                'last_category_id' => $categoryIds,
                'shop_id[!]' => self::$testShopIds
            ],
            'GROUP' => ['shop_id'],
        ]);

        return $shopIds;
    }

    /*
     * 检测商品是否存在
     * **/
    public static function checkGoodsById($id)
    {

        return self::get(['goods_id', 'title', 'status', 'min_price', 'max_price'], ['goods_id' => $id]);
    }

    public static function getFieldsByFilter($fields = [], $where = [])
    {
        $results = self::select($fields, $where);

        if (count($fields) == 1) {

            return array_map(function ($result) use ($fields) {
                return $result[$fields[0]];
            }, $results);
        } else {
            return $results;
        }
    }

    public static function getGoodsInfoByGoodsId($field, $ids)
    {

        return self::select($field, [
            'OR' => [
                'goods_id' => $ids
            ],
            'status' => self::STATUS_ONLINE,
        ]);
    }

    public static function getGoosdInfo()
    {
        return self::select('goods_id', [
            'AND' => [
                'status' => self::STATUS_ONLINE,
                'stock[>]' => 0,
                'shop_id[!]' => self::$testShopIds
            ],
            'ORDER' => ['addtime' => 'DESC'],
            'GROUP' => ['last_category_id'],
            'LIMIT' => 400,
        ]);
    }

    public static function getRecommedList($categoryId, $secondCategoryId, $thirdCategoryId, $fourCategoryId, array $filter)
    {
        $map = [];

        $map['AND'] = [
            'status' => [
                self::STATUS_PASSED,
                self::STATUS_ONLINE
            ]
        ];

        $map['AND']['OR'] = [
            'category_id' => $categoryId,
            'second_category_id' => $secondCategoryId,
        ];

        foreach ([$thirdCategoryId, $fourCategoryId] as $k => $v) {
            if ($v) {
                $map['AND']['OR'] = array_merge($map['AND']['OR'], $k == 0 ? ['third_category_id' => $v] : ['four_category_id' => $v]);
            }
        }


        $map['LIMIT'] = isset($filter['LIMIT']) ? $filter['LIMIT'] : [0, 20];

        if ($filter) {
            if (isset($filter['LIMIT'])) {
                unset($filter['LIMIT']);
            }

            $map['AND'] = array_merge($map['AND'], $filter);

        }

        $map['ORDER'] = [
            'four_category_id' => 'DESC',
            'third_category_id' => 'DESC',
            'second_category_id' => 'DESC',
            'category_id' => 'DESC',
            'sell_total' => 'DESC',
            'addtime' => 'DESC',
        ];


        return self::select('*', $map);
    }

    public static function getbidCounterByWikiId($wiki_id)
    {
        return self::count([
            'wiki_id' => $wiki_id,
            'status' => self::$statusAppCanSeeMap
        ]);
    }

    public static function getNormalBndCounterByWikiId($wiki_id)
    {
        return self::count([
            'wiki_id' => $wiki_id,
            'status' => self::$statusAppNormalMap
        ]);
    }

    public static function getOfflineBndCounterByWikiId($wiki_id)
    {
        return self::count([
            'wiki_id' => $wiki_id,
            'status' => self::$statusAppOffLineMap
        ]);
    }


    public static function is_has_goods($brand_id)
    {
        return self::get('*', [
            'brand_id' => $brand_id,
            'status' => self::$statusAppCanSeeMap
        ]) ? true : false;

    }

    public static function getSpuIdsByWiki(array $wiki_ids)
    {
        $infos = self::select(['goods_id', 'wiki_id'], [
            'wiki_id' => $wiki_ids,
            'status' => self::$statusAppCanSeeMap
        ]);

        $Rst = [];
        foreach ($infos as $info) {
            $Rst[$info['wiki_id']][] = $info['goods_id'];
        }
        return $Rst;

    }

    public static function getGoodsIdByTag($goodsIds, $order, $page, $pageSize)
    {
        $limit = [($page - 1) * $pageSize, $pageSize];

        $param = [
            'goods_id' => $goodsIds,
            'status' => self::STATUS_ONLINE,
            'stock[>]' => 0,
        ];

        return self::select('goods_id', [
            'AND' => $param,
            'ORDER' => $order,
            'LIMIT' => $limit
        ]);

    }

    public static function admIsAlarm($goodsId)
    {
        $info = self::get(["[>]operate_log(ol)" => ["gbi.goods_id" => "foreign_id"]], "*", [
            'goods_id' => $goodsId,
            'ol.type' => OperateLog::TYPE_GOODS_ALARM,
        ]);

        return $info ? 1 : 0;
    }

    /**
     * @desc 获取一级类目下的商品id集合
     * @param int $categoryId 一级类目id
     * @return array
     */
    public static function getGoodsIdsByCategoryId($categoryId)
    {
        $fields = [
            'goods_id',
        ];
        $where = [
            "category_id" => $categoryId
        ];
        return self::select($fields, $where);
    }

    /*
     * 获取商品
     */
    public static function getGoodsByWhere($method, $fields, $where)
    {
        $infoList = self::$method($fields, $where);

        $infoList = array_map(function ($v) {
            self::formatInfo($v);

            return $v;
        }, $infoList);

        return $infoList;

    }

    public static function updateByWhere($fields, $where)
    {
        return self::update($fields, $where)->rowCount();
    }

    public static function getLevel_1_2_CateIds($goodsIds, $formatStr = false)
    {
        $list = self::select(['goods_id', 'category_id', 'second_category_id'], ['goods_id' => $goodsIds]);

        $list = array_column($list, null, 'goods_id');

        if ($formatStr) {
            $list = array_map(function ($v) {
                return $v['category_id'] . '-' . $v['second_category_id'];
            }, $list);
        }
        return $list;
    }


    public static function getBasicInfoByAdmin($goodsId, $field = 'title')
    {
        return self::get($field, ['goods_id' => $goodsId, 'status' => self::STATUS_ONLINE]);
    }

}
